use std::fmt::Debug;

use rapier3d::geometry::{BroadPhaseMultiSap, Collider, ColliderSet};
use rapier3d::prelude::BroadPhase;
use rapier3d::{
    dynamics::{
        CCDSolver, ImpulseJointSet, IntegrationParameters, IslandManager, MultibodyJointSet,
        RigidBodySet,
    },
    geometry::NarrowPhase,
    na::Vector3,
    pipeline::{PhysicsPipeline, QueryPipeline},
};
use QcCore::scene_system::scene::Scene;
pub struct PhysicsEngine {
    rigid_body_set: RigidBodySet,
    collider_set: ColliderSet,
    physics_pipeline: PhysicsPipeline,
    island_manager: IslandManager,
    integration_parameters: IntegrationParameters,
    broad_phase: BroadPhaseMultiSap,
    narrow_phase: NarrowPhase,
    impulse_joint_set: ImpulseJointSet,
    multibody_joint_set: MultibodyJointSet,
    ccd_solver: CCDSolver,
    query_pipeline: QueryPipeline,
    gravity: Vector3<f32>,
}

impl Debug for PhysicsEngine {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.debug_struct("PhysicsEngine").finish()
    }
}

impl PhysicsEngine {
    pub fn new() -> Self {
        let rigid_body_set = RigidBodySet::new();
        let collider_set = ColliderSet::new();

        let physics_pipeline = PhysicsPipeline::new();
        let island_manager = IslandManager::new();
        let integration_parameters = IntegrationParameters::default();
        let physics_pipeline = PhysicsPipeline::new();
        let island_manager = IslandManager::new();
        let broad_phase = BroadPhaseMultiSap::new();
        let narrow_phase = NarrowPhase::new();
        let impulse_joint_set = ImpulseJointSet::new();
        let multibody_joint_set = MultibodyJointSet::new();
        let ccd_solver = CCDSolver::new();
        let query_pipeline = QueryPipeline::new();

        let gravity = Vector3::new(0., -9.8, 0.);
        Self {
            rigid_body_set,
            physics_pipeline,
            integration_parameters,
            broad_phase,
            narrow_phase,
            impulse_joint_set,
            multibody_joint_set,
            collider_set,
            ccd_solver,
            island_manager,
            query_pipeline,
            gravity,
        }
    }

    pub fn update(&mut self) {
        let physics_hooks = ();
        let event_handler = ();

        self.physics_pipeline.step(
            &self.gravity,
            &self.integration_parameters,
            &mut self.island_manager,
            &mut self.broad_phase,
            &mut self.narrow_phase,
            &mut self.rigid_body_set,
            &mut self.collider_set,
            &mut self.impulse_joint_set,
            &mut self.multibody_joint_set,
            &mut self.ccd_solver,
            Some(&mut self.query_pipeline),
            &physics_hooks,
            &event_handler,
        )
    }

    fn post_update(&mut self, scene: &mut Scene) {
        for (handle, body) in self.rigid_body_set.iter() {
            
        }
    }
}
